import {
  Body,
  Controller,
  DefaultValuePipe,
  Get,
  HttpStatus,
  Inject,
  Logger,
  Post,
  Query,
  UnauthorizedException,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { UserService } from './user.service';
import { LoginUserDto, RegisterUserDto } from './dto/create-user.dto';
import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import {
  RequireLogin,
  RequirePermission,
  UserInfo,
} from 'src/custom.decorator';
import { UpdateUserDto } from './dto/update-user.dto';
import { UpdatePasswordDto } from './dto/update-password.dto';
import { generateParseIntPipe } from 'src/utils/utils';
import { ApiBody, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger';

import { LoginUserVo } from './vo/login-user.vo';
import { FileInterceptor } from '@nestjs/platform-express';
import { Express } from 'express';
import * as path from 'path';
import { storage } from 'src/my-file-storage';

@ApiTags('用户管理')
@Controller('user')
export class UserController {
  constructor(private readonly userService: UserService) {}
  private logger = new Logger();

  @Inject(JwtService)
  private jwtService: JwtService;

  @Inject(ConfigService)
  private configService: ConfigService;

  @ApiBody({ type: RegisterUserDto })
  @ApiResponse({
    status: HttpStatus.OK,
    description: '注册成功/失败',
    type: String,
  })
  @Post('register')
  register(@Body() registerUserDto: RegisterUserDto) {
    console.log(registerUserDto);
    return this.userService.register(registerUserDto);
  }

  @ApiBody({ type: LoginUserDto })
  @ApiResponse({
    status: HttpStatus.OK,
    description: '用户信息和token',
    type: LoginUserVo,
  })
  @ApiResponse({
    status: HttpStatus.BAD_REQUEST,
    description: '用户名或密码错误',
    type: String,
  })
  @Post('login')
  async login(@Body() loginUserDto: LoginUserDto) {
    const vo = await this.userService.login(loginUserDto, false);
    vo.accessToken = this.jwtService.sign(
      {
        id: vo.userInfo.id,
        username: vo.userInfo.username,
        roles: vo.userInfo.roles,
        permissions: vo.userInfo.permissions,
      },
      {
        expiresIn: this.configService.get('jwt_expires_in'),
      },
    );
    vo.refreshToken = this.jwtService.sign(
      {
        id: vo.userInfo.id,
        username: vo.userInfo.username,
        roles: vo.userInfo.roles,
        permissions: vo.userInfo.permissions,
      },
      {
        expiresIn: this.configService.get('jwt_refresh_token_expres_time'),
      },
    );

    return vo;
  }

  @Post('adminLogin')
  async adminLogin(@Body() loginUserDto: LoginUserDto) {
    const vo = await this.userService.login(loginUserDto, true);
    vo.accessToken = this.jwtService.sign(
      {
        id: vo.userInfo.id,
        username: vo.userInfo.username,
        roles: vo.userInfo.roles,
        permissions: vo.userInfo.permissions,
      },
      {
        expiresIn: this.configService.get('jwt_expires_in'),
      },
    );
    vo.refreshToken = this.jwtService.sign(
      {
        id: vo.userInfo.id,
        username: vo.userInfo.username,
        roles: vo.userInfo.roles,
        permissions: vo.userInfo.permissions,
      },
      {
        expiresIn: this.configService.get('jwt_refresh_token_expres_time'),
      },
    );
    return vo;
  }

  @ApiQuery({
    name: 'email',
    description: '邮箱',
    required: true,
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: '验证码发送成功',
    type: String,
  })
  @Get('captcha')
  getCaptcha(@Query() query: { email: string }) {
    return this.userService.getCaptcha(query.email);
  }

  @Get('initData')
  initData() {
    return this.userService.initData();
  }
  @ApiQuery({
    name: 'refreshToken',
    description: '刷新token',
    required: true,
    example: 'xxxxxxxxxxxxx',
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: 'token 刷新成功',
  })
  @ApiResponse({
    status: HttpStatus.UNAUTHORIZED,
    description: 'token 无效,请重新登录',
  })
  @Get('refreshToken')
  refreshToken(@Query() query: { refreshToken: string }) {
    try {
      const payload = this.jwtService.verify(query.refreshToken);
      this.logger.log(payload, 'refreshToken payload');
      const accessToken = this.jwtService.sign(
        {
          id: payload.id,
          username: payload.username,
          roles: payload.roles,
          permissions: payload.permissions,
        },
        {
          expiresIn: this.configService.get('jwt_expires_in'),
        },
      );
      const refreshToken = this.jwtService.sign(
        {
          id: payload.id,
          username: payload.username,
          roles: payload.roles,
          permissions: payload.permissions,
        },
        {
          expiresIn: this.configService.get('jwt_refresh_token_expres_time'),
        },
      );
      return {
        accessToken,
        refreshToken,
      };
    } catch (e) {
      this.logger.error(e);
      throw new UnauthorizedException('token 无效,请重新登录');
    }
  }

  @ApiQuery({
    name: 'page',
    description: '当前页码',
    required: true,
    example: 1,
  })
  @ApiQuery({
    name: 'size',
    description: '每页条数',
    required: true,
    example: 10,
  })
  @ApiQuery({
    name: 'nickName',
    description: '昵称',
    required: false,
    example: '张三',
  })
  @ApiQuery({
    name: 'username',
    description: '用户名',
    required: false,
    example: 'zhangsan',
  })
  @ApiQuery({
    name: 'email',
    description: '邮箱',
    required: false,
    example: 'xx@xx.xx',
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: '用户列表',
  })
  @ApiResponse({
    status: HttpStatus.BAD_REQUEST,
    type: String,
  })
  @Get('list')
  @RequireLogin()
  @RequirePermission('ccc')
  list(
    @Query('page', new DefaultValuePipe(1), generateParseIntPipe('page'))
    page: number,
    @Query('size', new DefaultValuePipe(10), generateParseIntPipe('size'))
    size: number,
    @Query('nickName') nickName: string,
    @Query('username') username: string,
    @Query('email') email: string,
  ) {
    return this.userService.list(page, size, username, nickName, email);
  }

  @Get('info')
  @RequireLogin()
  info(@UserInfo('id') id: number) {
    return this.userService.info(id);
  }

  @Post(['update', 'admin/update'])
  @RequireLogin()
  update(@UserInfo('id') id: number, @Body() updateUserDto: UpdateUserDto) {
    return this.userService.update(id, updateUserDto);
  }

  @Post('updatePassword')
  @RequireLogin()
  updatePassword(
    @UserInfo('id') id: number,
    @Body() updatePasswordDto: UpdatePasswordDto,
  ) {
    return this.userService.updatePassword(id, updatePasswordDto);
  }

  @Get('freeze')
  @RequireLogin()
  freeze(@Query('id') userId: number) {
    return this.userService.freeze(userId);
  }
  @ApiBody({ type: UpdateUserDto })
  @Post('upload')
  @UseInterceptors(
    FileInterceptor(
      'file',

      {
        dest: 'uploads',
        storage: storage,
        fileFilter(req, file, cb) {
          const extname = path.extname(file.originalname);
          if (['.jpg', '.png', '.jpeg'].includes(extname)) {
            cb(null, true);
          } else {
            cb(new Error('文件类型错误'), false);
          }
        },
        limits: {
          fileSize: 1024 * 1024 * 3,
        },
      },
    ),
  )
  upload(@UploadedFile() file: Express.Multer.File) {
    console.log(file, 'file');
    return file.path;
    // return this.userService.upload(id, body);
  }
}
